/**
 * MessageServiceImpl.java
 * Created at 2018-2-22
 * Created by zhanghailin
 * Copyright (C) 2018 BROADTEXT SOFTWARE, All rights reserved.
 */
package com.broadtext.message.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.broadtext.common.exp.DaoException;
import com.broadtext.common.exp.ServiceException;
import com.broadtext.common.repository.EntityDao;
import com.broadtext.common.service.impl.EntityServiceImpl;
import com.broadtext.common.utils.DateUtils;
import com.broadtext.common.utils.StringUtils;
import com.broadtext.common.utils.UUIDUtils;
import com.broadtext.message.AppPushUtils;
import com.broadtext.message.model.AppUserClient;
import com.broadtext.message.model.SysMessage;
import com.broadtext.message.service.IMessageService;
import com.gexin.rp.sdk.base.IPushResult;

/**
 * <p>ClassName: MessageServiceImpl</p>
 * <p>Description: TODO</p>
 * <p>Author: zhanghailin</p>
 * <p>Date: 2018-2-22</p>
 */
@Service("messageService")
public class MessageServiceImpl extends EntityServiceImpl<SysMessage> implements IMessageService{
    
    Logger logger = LoggerFactory.getLogger(MessageServiceImpl.class);
    
    /**
     * 
     * <p>Description: 基类dao</p>
     * @param entityDao 基类实体dao
     */
    @Autowired
    @Qualifier("messageDao")
    public void setEntityDao(EntityDao<SysMessage> entityDao) {
        super.entityDao = entityDao;
    }

    /** (non-Javadoc)
     * <p>Title: insertAlertMessage</p>
     * <p>Description: 在message表中插入消息类型为告警的消息</p>
     * @throws DaoException 
     * @see com.broadtext.message.service.IMessageService#insertAlertMessage()
     */
    @Override
    public void insertAlertMessage() throws DaoException {
        String type = "alertMessage";
        String gatherTimeStart = this.getTasktime(type);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("gatherTimeStart", gatherTimeStart);
        //获取当前时间
        String gatherTimeEnd = DateUtils.getCurrentTime();
        params.put("gatherTimeEnd", gatherTimeEnd);
        //结转数据
        this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.insertAlertMessageData", params);
        //更新时间
        updateTaskTime(type,gatherTimeEnd);
    }

    /** (non-Javadoc)
     * <p>Title: insertAlertData</p>
     * <p>Description: </p>
     * @throws DaoException
     * @throws ServiceException
     * @see com.broadtext.message.service.IMessageService#insertAlertData()
     */
    @Override
    public void insertAlertData() throws DaoException {
        String type = "alert";
        String gatherTimeStart = this.getTasktime("alert");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("gatherTimeStart", gatherTimeStart);
        //获取当前时间
        String gatherTimeEnd = DateUtils.getCurrentTime();
        params.put("gatherTimeEnd", gatherTimeEnd);
        //结转数据
        this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.insertAlertData", params);
        //更新时间
        updateTaskTime(type,gatherTimeEnd);
    }
    
    /**
     * 
     * <p>Description: 查询结转时间</p>
     * @param type
     * @return
     * @throws DaoException
     */
    @SuppressWarnings("unchecked")
    private String getTasktime(String type) throws DaoException{
        String time = "";
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("type", type);
        List<Map<String, Object>> list = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getTasktime", params);
        if(list!=null&&list.size()>0&&list.get(0)!=null) {
            time = String.valueOf(list.get(0).get("gatherTimeStart"));
        }
        return time;
    }
    
    /**
     * 
     * <p>Description: 更新结转时间</p>
     * @param type
     * @param time
     * @throws DaoException
     */
    private void updateTaskTime(String type, String time) throws DaoException{
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("type", type);
        params.put("gatherTimeEnd", time);
        this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.updateTaskTime", params);
    }

    /** (non-Javadoc)
     * <p>Title: getMessageNotification</p>
     * <p>Description: 根据用户id获取用户消息通知</p>
     * @param receiver
     * @return
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#getMessageNotification(java.lang.String)
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<Object> getMessageNotification(String receiver) throws DaoException {
        List<Object> messageList = new ArrayList<Object>();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("receiver", receiver);
        messageList = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getMessageNotification", params);
        return messageList;
    }

    /** (non-Javadoc)
     * <p>Title: BindAppClientId</p>
     * <p>Description: </p>
     * @param loginName
     * @param clientId
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#BindAppClientId(java.lang.String, java.lang.String)
     */
    @Override
    public void bindAppClientId(String loginName, String clientId) throws DaoException {
        //根据登录名查pk_id
        String sysUserId = this.getUserPrimaryKey(loginName);
        if(StringUtils.isNotBlank(clientId)&&StringUtils.isNotBlank(sysUserId)) {
          //先解绑，防止重复绑定
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("clientId", clientId);
            this.entityDao.deleteRecord("com.broadtext.message.model.SysMessage.unBindAppClientId", params);
            AppUserClient record = new AppUserClient();
            record.setPkId(UUIDUtils.getUUID());
            record.setSysUserId(sysUserId);
            record.setClientId(clientId);
            record.setDelFlag("0");
            record.setCreateUser("system");
            record.setCreateDate(new Date());
            //绑定
            this.entityDao.insertRecord("com.broadtext.message.model.SysMessage.BindAppClientId", record);
        }
        
    }

    /** (non-Javadoc)
     * <p>Title: UnBindAppClientId</p>
     * <p>Description: </p>
     * @param loginName
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#UnBindAppClientId(java.lang.String)
     */
    @Override
    public void unBindAppClientId(String loginName,String clientId) throws DaoException {
        //根据登录名查pk_id
        String sysUserId = this.getUserPrimaryKey(loginName);
        if(StringUtils.isNotBlank(sysUserId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("sysUserId", sysUserId);
            params.put("clientId", clientId);
            this.entityDao.deleteRecord("com.broadtext.message.model.SysMessage.unBindAppClientId", params);
        }
    }
    
    
    @SuppressWarnings("unchecked")
    private String getUserPrimaryKey(String loginName) throws DaoException {
        String pkId = "";
        List<String> list = new ArrayList<String>();
        list = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getUserPrimaryKey", loginName);
        if(list!=null&&list.size()>0&&list.get(0)!=null) {
            pkId = list.get(0);
        }
        return pkId;
    }

    /** (non-Javadoc)
     * <p>Title: PushMessage2App</p>
     * <p>Description:没有使用确认机制，无法确认消息是否推送成功，其实可以使用mq来做 </p>
     * @throws DaoException
     * @throws IOException 
     * @throws JsonMappingException 
     * @throws JsonGenerationException 
     * @see com.broadtext.message.service.IMessageService#PushMessage2App()
     */
    @SuppressWarnings("unchecked")
    @Override
    public void pushMessage2App() throws DaoException, JsonGenerationException, JsonMappingException, IOException {
        //查询上次消息推送时间
        String gatherTimeStart = this.getTasktime("message");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("gatherTimeStart", gatherTimeStart);
        //获取当前时间
        String gatherTimeEnd = DateUtils.getCurrentTime();
        params.put("gatherTimeEnd", gatherTimeEnd);
        List<SysMessage> messageList = new ArrayList<SysMessage>();
        ObjectMapper json = new ObjectMapper();
        AppPushUtils app = new AppPushUtils();
        messageList = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getAppPushMessage", params);
        for (SysMessage sysMessage : messageList) {
            //for 循环中抓取异常，出错后循环继续，防止一次异常所有通知无法
            try {
                Map<String, Object> msg = new HashMap<String, Object>();
                // 组装透穿消息内容
                msg.put("title", sysMessage.getMessageTitle());
                msg.put("content", sysMessage.getMessageContent());
                Map<String,String> payload = new HashMap<String, String>();
                //消息类型
                payload.put("messageType", sysMessage.getMessageType());
                //消息主键
                payload.put("pkId", String.valueOf(sysMessage.getPkId()));
                msg.put("payload", payload);
                if(StringUtils.isNotBlank(sysMessage.getClientId())) {
                    logger.info("begin push message to clientId:{},msg:{}",sysMessage.getClientId(),json.writeValueAsString(msg));
                    //调用个推sdk推送消息至app客户端，统一推送透穿消息
                    IPushResult result = app.pushTransmissionMsgToSingle(sysMessage.getClientId(), json.writeValueAsString(msg));
                    logger.info("push message end ,{}",String.valueOf(result.getResponse()));
                }
            } catch (Exception e) {
                logger.error("push message to app error",e);
                continue;
            }
            
        }
        
        //更新时间
        updateTaskTime("message",gatherTimeEnd);
        
    }
    
    public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper json = new ObjectMapper();
        Map<String, Object> msg = new HashMap<String, Object>();
        // 组装透穿消息内容
        msg.put("title", "this is title");
        msg.put("content", "this is content");
        Map<String,String> payload = new HashMap<String, String>();
        payload.put("messageType", "1");
        msg.put("payload", payload);
        System.out.println(json.writeValueAsString(msg));
    }

    /** (non-Javadoc)
     * <p>Title: getMessageById</p>
     * <p>Description: </p>
     * @param pkId
     * @return
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#getMessageById(java.lang.Long)
     */
    @SuppressWarnings("unchecked")
    @Override
    public SysMessage getMessageById(Long pkId) throws DaoException {
        SysMessage message = new SysMessage();
        List<SysMessage> list = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getMessageById", pkId);
        if(list!=null && list.size()>0 &&list.get(0) !=null) {
            message = list.get(0);
            this.readMessage(new Long[]{pkId});
        }
        return message;
    }

    /** (non-Javadoc)
     * <p>Title: readMessage</p>
     * <p>Description: </p>
     * @param idArray
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#readMessage(java.lang.Long[])
     */
    @Override
    public void readMessage(Long[] idArray) throws DaoException {
        for (Long pkId : idArray) {
            SysMessage msg = new SysMessage();
            msg.setPkId(pkId);
            msg.setMessageStatus("1");
            this.entityDao.updateRecord("com.broadtext.message.model.SysMessage.updateRecord", msg);
        }
    }
    
    /** (non-Javadoc)
     * <p>Title: readMessage</p>
     * <p>Description: </p>
     * @param idArray
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#readMessage(java.lang.Long)
     */
    @Override
    public void readMessage(Long pkId) throws DaoException {
        SysMessage msg = new SysMessage();
        msg.setPkId(pkId);
        msg.setMessageStatus("1");
        this.entityDao.updateRecord("com.broadtext.message.model.SysMessage.updateRecord", msg);
    }

    /** (non-Javadoc)
     * <p>Title: deleteMessage</p>
     * <p>Description: </p>
     * @param idArray
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#deleteMessage(java.lang.Long[])
     */
    @Override
    public void deleteMessage(Long[] idArray) throws DaoException {
        for (Long pkId : idArray) {
            SysMessage msg = new SysMessage();
            msg.setPkId(pkId);
            msg.setDelFlag("1");
            this.entityDao.updateRecord("com.broadtext.message.model.SysMessage.updateRecord", msg);
        }
        
    }

    /** (non-Javadoc)
     * <p>Title: readAllMessage</p>
     * <p>Description: </p>
     * @param receiver
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#readAllMessage(java.lang.String)
     */
    @Override
    public void readAllMessage(String receiver) throws DaoException {
        this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.readAllMessage", receiver);
    }

    /** (non-Javadoc)
     * <p>Title: insertMessage</p>
     * <p>Description: </p>
     * @param message
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#insertMessage(com.broadtext.message.model.SysMessage)
     */
    @Override
    public Long insertMessage(SysMessage message) throws DaoException {
        message.setPkId(null);
        SqlSession session = this.entityDao.getCurrentSession();
        session.insert("com.broadtext.message.model.SysMessage.insertMessage", message);
        session.close();
        System.out.println(message.getPkId()+"++++++++++++++++++++++++++++++++++++++++++++>>>>>>>>");
        return message.getPkId();
        
    }

    /** (non-Javadoc)
     * <p>Title: getMessageCount</p>
     * <p>Description: </p>
     * @param receiver
     * @return
     * @throws DaoException
     * @see com.broadtext.message.service.IMessageService#getMessageCount(java.lang.String)
     */
    @SuppressWarnings("unchecked")
    @Override
    public Long getMessageCount(String receiver) throws DaoException {
        Long count = 0L;
        List<Long> counts = this.entityDao.findByProperty("com.broadtext.message.model.SysMessage.getMessageNotificationCount", receiver);
        if(counts!=null&&counts.size()>0&&counts.get(0)!=null){
            count = counts.get(0);
        }
        return count;
    }
     

}
